
def extract_wx_from_layout(layout, **kwargs):
    """
    params:
        type    [cls]: 查找第一个指定类型的widget对象，如未找到返回None
        typeall [cls]: 返回layout中指定类型的所有widget对象的映射字典
        id      [str]: 根据widget的objectName，查找指定对象，如未找到返回None
        index   [int]: 根据该layout对象addWidget的顺序，提取widget对象
        None         : 返回layout中所有widget对象的映射字典

    return a dict for [typeall], like this:
        widget_dict = {
            "push_btn_id": QPushButton-Object,
            "btn_id_2"   : QPushButton-Object,
            ...
        }
    """
    if "index" in kwargs:
        # 如index越界，则程序执行异常
        return layout.itemAt(kwargs["index"]).widget()

    dict_ret = {}
    for index in range(layout.count()):
        layout_item = layout.itemAt(index)
        layout_sub_widget = layout_item.widget()  # 获取到widget对象
        wx_id = layout_sub_widget.objectName

        if "id" in kwargs and kwargs["id"] == wx_id:
            return layout_sub_widget
        elif "type" in kwargs and isinstance(layout_sub_widget, kwargs["type"]):
            return layout_sub_widget
        # elif kwargs["typeall"] and isinstance(layout_sub_widget, kwargs["type"]):
        elif "typeall" in kwargs and not isinstance(layout_sub_widget, kwargs["typeall"]):
            continue
        dict_ret[wx_id] = layout_sub_widget

    return dict_ret


def extract_wx_from_container(container, **kwargs):
    layout = container.layout()
    if not layout:
        raise Exception("This containenr [{}] has NO layout.".format(container))

    return extract_wx_from_layout(layout, **kwargs)
